/*
 * @Author       : hwl
 * @Date         : 2021-05-06 08:07:08
 * @LastEditors  : hwl
 * @LastEditTime : 2021-05-07 10:14:10
 * @FilePath     : e:\HBuilderProjects\vue3-demo\02_Vue3\vue3_study\01_代码\20_手写组合API\index.js
 * @Description  :
 */
// shallowReactive reactive
const reactiveHandler = {
  get (target, prop) {
    if (prop==='_is_reactive') return true
    const result = Reflect.get(target, prop)
    console.log('get', prop, result)
    return result
  },
  set (target, prop ,value) {
    console.log(target, prop ,value)
    const result = Reflect.set(target, prop, value)
    console.log('set', target, prop ,value)
    return result
  },
  deleteProperty (target, prop) {
    const result = Reflect.deleteProperty(target, prop)
    console.log('delete', prop)
    return result
  }
}
function shallowReactive (target) {
  if(target && typeof target === 'object') {
    return new Proxy(target, reactiveHandler)
  }
  return target
}

function reactive (target) {
  if(target && typeof target === 'object') {
    if(Array.isArray(target)) {
      target.forEach((item,index) => {
        target[index] = reactive(item)
      })
    }else{
      Object.keys(target).forEach(key => {
        target[key] = reactive(target[key])
      })
    }
    return new Proxy(target, reactiveHandler)
  }
  return target
}

// shallowRef 与 ref
function shallowRef(target) {
  const result = {
    _value: target, // 用来保存数据的内部属性
    _is_ref: true, // 用来标识是ref对象
    get value () {
      return this._value
    },
    set value (val) {
      this._value = val
      console.log('set value 数据已更新, 去更新界面')
    }
  }

  return result
}

function ref(target) {
  if (target && typeof target==='object') {
    target = reactive(target)
  }

  const result = {
    _value: target, // 用来保存数据的内部属性
    _is_ref: true, // 用来标识是ref对象
    get value () {
      return this._value
    },
    set value (val) {
      this._value = val
      console.log('set value 数据已更新, 去更新界面')
    }
  }

  return result
}

// shallowReadonly 与 readonly
const readonlyHandler = {
  get (target, key) {
    if (key==='_is_readonly') return true

    return Reflect.get(target, key)
  },

  set () {
    console.warn('只读的, 不能修改')
    return true
  },

  deleteProperty () {
    console.warn('只读的, 不能删除')
    return true
  },
}

/*
自定义shallowReadonly
*/
function shallowReadonly(obj) {
  return new Proxy(obj, readonlyHandler)
}

/*
自定义readonly
*/
function readonly(target) {
  if (target && typeof target==='object') {
    if (target instanceof Array) { // 数组
      target.forEach((item, index) => {
        target[index] = readonly(item)
      })
    } else { // 对象
      Object.keys(target).forEach(key => {
        target[key] = readonly(target[key])
      })
    }
    const proxy = new Proxy(target, readonlyHandler)

    return proxy
  }

  return target
}

// isRef, isReactive 与 isReadonly
/*
判断是否是ref对象
*/
function isRef(obj) {
  return obj && obj._is_ref
}

/*
判断是否是reactive对象
*/
function isReactive(obj) {
  return obj && obj._is_reactive
}

/*
判断是否是readonly对象
*/
function isReadonly(obj) {
  return obj && obj._is_readonly
}

/*
是否是reactive或readonly产生的代理对象
*/
function isProxy (obj) {
  return isReactive(obj) || isReadonly(obj)
}


